package cn.edu.cug.cs.gtl.apis.ui.tree;



import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;

public class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor {

    private final TreeNodeRenderer renderer = new TreeNodeRenderer();

    private final JTree theTree;

    public TreeNodeEditor(final JTree tree) {
        theTree = tree;
    }

    @Override
    public Object getCellEditorValue() {
        final TreeNodePanel panel = renderer.getPanel();
        final TreeNodeData checkBoxNode =
                new TreeNodeData(panel.refObject,panel.label.getText(), panel.check.isSelected());
        return checkBoxNode;
    }

    @Override
    public boolean isCellEditable(final EventObject event) {
        if (!(event instanceof MouseEvent)) return false;
        final MouseEvent mouseEvent = (MouseEvent) event;

        final TreePath path =
                theTree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
        if (path == null) return false;

        final Object node = path.getLastPathComponent();
        if (!(node instanceof DefaultMutableTreeNode)) return false;
        final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;

        final Object userObject = treeNode.getUserObject();
        return userObject instanceof TreeNodeData;
    }

    @Override
    public Component getTreeCellEditorComponent(final JTree tree,
                                                final Object value, final boolean selected, final boolean expanded,
                                                final boolean leaf, final int row)
    {

        final Component editor =
                renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf,
                        row, true);

        // editor always selected / focused
        final ItemListener itemListener = new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent itemEvent) {
                if (stopCellEditing()) {
                    fireEditingStopped();
                }
            }
        };
        if (editor instanceof TreeNodePanel) {
            final TreeNodePanel panel = (TreeNodePanel) editor;
            panel.check.addItemListener(itemListener);
        }

        return editor;
    }
}
